/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.drawee.drawable;

import com.facebook.common.internal.VisibleForTesting;
import com.facebook.imagepipeline.systrace.FrescoSystrace;
import com.oszc.bbhmlibrary.utils.CommonUtils;
import com.oszc.bbhmlibrary.utils.LogUtil;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.media.image.PixelMap;

import javax.annotation.Nullable;
import java.lang.ref.WeakReference;

public class RoundedBitmapDrawable extends RoundedDrawable {

  private final String TAG = RoundedBitmapDrawable.class.getSimpleName();

  private final Paint mPaint = new Paint();
  private final Paint mBorderPaint = new Paint();
  @Nullable private final PixelMap mBitmap;
  private WeakReference<PixelMap> mLastBitmap;
  private PixelMapShader mPixelMapShader;

  public RoundedBitmapDrawable(@Nullable PixelMap bitmap, @Nullable Paint paint) {
    super(new PixelMapElement(bitmap));
    mBitmap = bitmap;
    if (paint != null) {
      mPaint.set(paint);
    }

    mPaint.setAntiAlias(true);
    mBorderPaint.setAntiAlias(true);
    mBorderPaint.setStyle(Paint.Style.STROKE_STYLE);
  }

  @Override
  public int getIntrinsicWidth() {
    if(mBitmap!=null) {
      return mBitmap.getImageInfo().size.width;
    }
    return super.getIntrinsicWidth();
  }

  @Override
  public int getIntrinsicHeight() {
    if(mBitmap!=null) {
      return mBitmap.getImageInfo().size.height;
    }
    return super.getIntrinsicHeight();
  }

  @Override
  public void setBounds(Rect bounds) {
    super.setBounds(bounds);
  }

  @Override
  public void setBounds(int left, int top, int right, int bottom) {
    super.setBounds(left, top, right, bottom);
  }

  public RoundedBitmapDrawable(PixelMap bitmap) {
    this(bitmap,null);
  }

  @Override
  public void drawToCanvas(Canvas canvas) {
      LogUtil.error(TAG,"drawToCanvas A mBorderWidth:"+ mBorderWidth +"     shouldRound:"+shouldRound());
    if (FrescoSystrace.isTracing()) {
      FrescoSystrace.beginSection("RoundedBitmapDrawable#draw");
    }
    if (!shouldRound()) {
      LogUtil.error(TAG,"drawToCanvas B");
      super.drawToCanvas(canvas);
      if (FrescoSystrace.isTracing()) {
        FrescoSystrace.endSection();
      }
      return;
    }
    updateTransform();
    updatePath();
    updatePaint();

    int saveCount = canvas.save();
    canvas.concat(mInverseParentTransform);
    canvas.drawPath(mPath, mPaint);

    if (mBorderWidth > 0) {
      mBorderPaint.setStrokeWidth(mBorderWidth);
      mBorderPaint.setColor(new Color(DrawableUtils.multiplyColorAlpha(mBorderColor, (int)mPaint.getAlpha())));
      canvas.drawPath(mBorderPath, mBorderPaint);
    }
    canvas.restoreToCount(saveCount);
    if (FrescoSystrace.isTracing()) {
      FrescoSystrace.endSection();
    }
  }

  private void updatePaint() {
    LogUtil.error(TAG,"updatePaint A");
    if (mLastBitmap == null || mLastBitmap.get() != mBitmap) {
      LogUtil.error(TAG,"updatePaint B");
      mLastBitmap = new WeakReference<>(mBitmap);
      mPixelMapShader = new PixelMapShader(new PixelMapHolder(mBitmap),
              Shader.TileMode.CLAMP_TILEMODE,
              Shader.TileMode.CLAMP_TILEMODE);
      mIsShaderTransformDirty = true;

    }
    if (mIsShaderTransformDirty) {
      LogUtil.error(TAG,"updatePaint C");
      //Paint.getShader don't work in  harmonyOS  in api version 4 build 2.1.0.10
      if(mPixelMapShader!=null){
        LogUtil.error(TAG,"updatePaint C1");
        mPixelMapShader.setShaderMatrix(mTransform);
        mPaint.setShader(mPixelMapShader,Paint.ShaderType.PIXELMAP_SHADER);
        CommonUtils.printMatrix(mTransform);
      }
      mIsShaderTransformDirty = false;
    }
    mPaint.setFilterBitmap(getPaintFilterBitmap());
  }

  /**
   * Creates a new RoundedBitmapDrawable from the given BitmapDrawable.
   *
//   * @param res resources to use for this drawable
   * @param bitmapDrawable bitmap drawable containing the bitmap to be used for this drawable
   * @return the RoundedBitmapDrawable that is created
   */
  public static RoundedBitmapDrawable fromBitmapDrawable(PixelMapElement bitmapDrawable) {
    return new RoundedBitmapDrawable(bitmapDrawable.getPixelMap(), null);
  }

  /** If both the radii and border width are zero or bitmap is null, there is nothing to round. */
  @VisibleForTesting
  boolean shouldRound() {
    return super.shouldRound() && mBitmap != null;
  }

  @Override
  public void setAlpha(int alpha) {
    super.setAlpha(alpha);
    if (alpha != mPaint.getAlpha()) {
      mPaint.setAlpha(alpha);
      super.setAlpha(alpha);
      invalidateSelf();
    }
  }

  @Override
  public void invalidateSelf() {
      if(getCallback()!=null){
        getCallback().onChange(this);
      }
  }

  @Override
  public void setColorFilter(ColorFilter colorFilter) {
    mPaint.setColorFilter(colorFilter);
  }

  Paint getPaint() {
    return mPaint;
  }
}
